/**
 * 用户管理模块
 */
const router = require('koa-router')()
const User = require('./../models/userSchema')
const Counter = require('./../models/counterSchema')
const Menu = require('./../models/menuSchema')
const Role = require('./../models/roleSchema')
const util = require('./../utils/util')
const jwt = require('jsonwebtoken')
const md5 = require('md5')
router.prefix('/users')

// 用户登录
router.post('/login', async (ctx) => {
  try {
    const { userName, userPwd } = ctx.request.body;
    const res = await User.findOne({
      userName,
      userPwd: md5(userPwd)
    }, 'userId userName userEmail state role deptId roleList createTime')

    // 如果匹配到此用户
    if (res) {
      const data = res._doc;

      // token
      const token = jwt.sign({
        data
      }, 'cyj', { expiresIn: '24h' })
      data.token = token;
      ctx.body = util.success(data)
    } else {
      ctx.body = util.fail("账号或密码不正确")
    }
  } catch (error) {
    ctx.body = util.fail(error.msg)
  }
})

// 用户修改密码
router.post('/editPassword', async (ctx) => {
  const { oldUserPwd, userPwd, userId } = ctx.request.body;
  const res = await User.findOne({
    userId,
    userPwd: md5(oldUserPwd)
  })
  if (res == null) {
    ctx.body = util.fail("原密码有误")
  } else {
    const res2 = await User.findOneAndUpdate({ userId }, { userPwd: md5(userPwd) })
    ctx.body = util.success(res2, '修改密码成功')
  }
})

// 用户列表
router.get('/list', async (ctx) => {
  //   解构拿到请求条件
  const { userId, userName, state } = ctx.request.query;
  //   拿到pageNum,pageSize,和后端查询逻辑skipIndex
  const { page, skipIndex } = util.pager(ctx.request.query)
  let params = {}

  // 拿到查询参数
  if (userId) params.userId = userId;
  if (userName) params.userName = userName;
  if (state && state != '0') params.state = state;
  try {
    // 根据条件查询所有用户列表 (不返回主键id和密码)
    const query = User.find(params, { _id: 0, userPwd: 0 })
    // 跳到skipIndex开始,然后读取pageSize条数据
    const list = await query.skip(skipIndex).limit(page.pageSize)
    // 根据条件计算数据总条数
    const total = await User.countDocuments(params);

    ctx.body = util.success({
      page: {
        ...page,
        total
      },
      list
    })
  } catch (error) {
    ctx.body = util.fail(`查询异常:${error.stack}`)
  }
})

// 获取全量用户列表
router.get('/all/list', async (ctx) => {
  try {
    const list = await User.find({}, "userId userName userEmail")
    ctx.body = util.success(list)
  } catch (error) {
    ctx.body = util.fail(error.stack)
  }
})

// // 用户删除/批量删除
// router.post('/delete', async (ctx) => {
//   // 待删除的用户Id数组
//   const { userIds } = ctx.request.body
//   // User.updateMany({ $or: [{ userId: 10001 }, { userId: 10002 }] })
//   const res = await User.updateMany({ userId: { $in: userIds } }, { state: 2 })

//   // 判断是否修改
//   if (res.nModified) {
//     ctx.body = util.success(res, `共删除成功${res.nModified}条`)
//     return;
//   }
//   ctx.body = util.fail('删除失败');
// })

// 用户删除/批量删除
router.post('/delete', async (ctx) => {
  // 待删除的用户Id数组
  const { userId } = ctx.request.body
  // User.updateMany({ $or: [{ userId: 10001 }, { userId: 10002 }] })
  // User.update({ $or: [{ userId: 10001 }, { userId: 10002 }] })
  const res = await User.updateOne({ userId }, { state: 2 })
  // const res = await User.updateMany({ userId: { $in: userIds } }, { state: 2 })
  if (res.nModified) {
    ctx.body = util.success(res, `共删除成功${res.nModified}条`)
    return;
  } else {
    const new_res = await User.deleteOne({ userId })
    ctx.body = util.success(new_res, '删除成功');
    return;
  }
})

// 获取正式员工/实习员工/离职员工数量信息
router.get('/getMemberNum', async (ctx) => {
  // 不需要拿参数
  const res = await User.find({})
  let result = {
    zx: 0,
    sx: 0,
    lz: 0
  }
  res.forEach(item => {
    if (item.state === 1) {
      result.zx++
    } else if (item.state === 2) {
      result.lz++
    } else {
      result.sx++
    }
  })
  ctx.body = util.success(result)

})


// 用户新增/编辑
router.post('/operate', async (ctx) => {
  // 解构请求所传参
  const { userId, userName, userEmail, mobile, job, state, roleList, deptId, action } = ctx.request.body;

  // 判断是否为新增用户请求
  if (action == 'add') {
    // 判断必要参数是否传 (前端部分已经做过表单限制,二次验证)
    if (!userName || !userEmail || !deptId) {
      ctx.body = util.fail('参数错误', util.CODE.PARAM_ERROR)
      return;
    }
    // findOne 查询单条
    // 返回_id userName userEmail
    const res = await User.findOne({ $or: [{ userName }, { userEmail }] }, '_id userName userEmail')

    // 判断数据库中是否已经有用户名或者邮箱重复的用户存在
    if (res) {
      ctx.body = util.fail(`系统监测到有重复的用户，信息如下：${res.userName} - ${res.userEmail}`)
    } else {
      // $inc 自增操作
      // 查询并更新 用户自增表
      const doc = await Counter.findOneAndUpdate({ _id: 'userId' }, { $inc: { sequence_value: 1 } }, {})
      try {
        const user = new User({
          // 使用用户自增表+1的值作为userId 确保不会重复
          userId: doc.sequence_value,
          userName,
          // 初始化的新增用户默认密码写死 后期考虑时间够不够 写一个用户自修改密码
          userPwd: md5('123456'),
          userEmail,
          role: 1, //默认普通用户
          roleList, // 系统角色
          job,
          state,
          deptId,
          mobile
        })
        // save:主键不相同,自动插入这个对象
        user.save();
        ctx.body = util.success('', '用户创建成功');
      } catch (error) {
        ctx.body = util.fail(error.stack, '用户创建失败');
      }
    }
  } else {
    if (!deptId) {
      // 判断必要参数是否传 (前端部分已经做过表单限制,二次验证)
      ctx.body = util.fail('部门不能为空', util.CODE.PARAM_ERROR)
      return;
    }
    try {
      // 根据用户的userid查询并且更新
      const res = await User.findOneAndUpdate({ userId }, { mobile, job, state, roleList, deptId, })
      ctx.body = util.success({}, '更新成功')
    } catch (error) {
      ctx.body = util.fail(error.stack, '更新失败')
    }
  }
})

// 获取用户对应的权限
router.get("/getPermissionList", async (ctx) => {
  // 拿到请求头中的token
  let authorization = ctx.request.headers.authorization
  let { data } = util.decoded(authorization)
  // 获取菜单树 参数分别是用户角色(0管理员/1普通用户)和系统角色(人事/管理/研发/...)
  let menuList = await getMenuList(data.role, data.roleList);
  // 获取按钮权限数组
  let actionList = getAction(JSON.parse(JSON.stringify(menuList)))
  ctx.body = util.success({ menuList, actionList });
})

// 获取对应的权限菜单树
async function getMenuList(userRole, roleKeys) {
  let rootList = []

  // 如果是管理员权限 直接拿到所有权限模块
  if (userRole == 0) {
    rootList = await Menu.find({}) || []
  } else {
    // 根据用户拥有的角色，获取权限列表
    // 先查找用户对应的角色有哪些
    let roleList = await Role.find({ _id: { $in: roleKeys } })
    let permissionList = []

    // 对通过用户查询到的对应角色数组进行遍历查找
    roleList.map(role => {
      // role就是用户所拥有的角色对象,每个对象都拥有一个权限列表
      // 其中权限列表中有 checkedKeys 和 halfCheckedKeys
      let { checkedKeys, halfCheckedKeys } = role.permissionList;
      // 将两个权限拼接成一个数组
      permissionList = permissionList.concat([...checkedKeys, ...halfCheckedKeys])
    })
    // 去除重复权限
    permissionList = [...new Set(permissionList)]
    // 通过权限数组中的id匹配菜单数据表中符合权限的菜单
    rootList = await Menu.find({ _id: { $in: permissionList } })
  }
  // 按照树形结构返回
  return util.getTreeMenu(rootList, null, [])
}

function getAction(list) {
  let actionList = []
  // 递归获取所有按钮权限 数组
  const deep = (arr) => {
    while (arr.length) {
      let item = arr.pop();
      if (item.action) {
        item.action.map(action => {
          actionList.push(action.menuCode)
        })
      }
      if (item.children && !item.action) {
        deep(item.children)
      }
    }
  }
  deep(list)
  return actionList;
}
module.exports = router